package service

import (
	"fmt"
	ClickHouse "gin/database"
	"gin/model"
	"gin/types"
	"strings"
)

type NoteEntityRelation struct {
}

//GetAssetFeedbackAffectedShotCount 获取资产反馈影响的镜头数量
func (n *NoteEntityRelation) GetAssetFeedbackAffectedShotCount(reviewFeedbackId uint64) (res types.GetAssetFeedbackAffectedShotCountRes, err error) {
	err = ClickHouse.DB.Model(&model.NoteEntityRelation{}).
		Joins("join relation_note_entity_relation on note_entity_relation.id = relation_note_entity_relation.note_entity_relation_id").
		Where("note_entity_relation.review_feedback_id =? and note_entity_relation.relate_module_code = 'asset'", reviewFeedbackId).
		Select("count(DISTINCT relation_note_entity_relation.entity_id) as affected_shot_count").
		Take(&res).Error
	return
}

//GetShotFeedbackStepCategoryCount 获取镜头反馈工序上百分比
func (n *NoteEntityRelation) GetShotFeedbackStepCategoryCount(reviewFeedbackId uint64, projectId uint64, initEpisodeCodes string) (res types.GetShotFeedbackStepCategoryCountRes, err error) {

	// 拿取到环节信息
	// 格式: 返修率-统计 (类型-统计  必改-统计 接受-统计)
	// 计算: 同一镜头下同一环节同一类型 算作一个 / 总镜头数

	type noteEntityRelationList struct {
		EntityId       int64  `json:"entity_id" gorm:"column:entity_id"`
		StepCategoryId string `json:"step_category_id" gorm:"column:step_category_id"`
		ReasonType     string `json:"reason_type" gorm:"column:reason_type"`
	}

	var result []noteEntityRelationList
	var markModifyResult []noteEntityRelationList
	var demandStatusResult []noteEntityRelationList
	var repairResult []noteEntityRelationList

	// 获取类型个数
	resultQuery := ClickHouse.DB.Model(&model.NoteEntityRelation{}).
		Joins("join note on note.id = note_entity_relation.note_id")

	//必改
	markModifyResultQuery := ClickHouse.DB.Model(&model.NoteEntityRelation{}).
		Joins("join note on note.id = note_entity_relation.note_id")

	// 接受
	demandStatusResultQuery := ClickHouse.DB.Model(&model.NoteEntityRelation{}).
		Joins("join note on note.id = note_entity_relation.note_id")

	repairResultQuery := ClickHouse.DB.Model(&model.NoteEntityRelation{}).
		Joins("join note on note.id = note_entity_relation.note_id")

	if initEpisodeCodes != "" {
		resultQuery = resultQuery.
			Joins("join entity on entity.id = note_entity_relation.entity_id").
			Where("entity.initial_episode_code = ?", initEpisodeCodes)

		markModifyResultQuery = markModifyResultQuery.
			Joins("join entity on entity.id = note_entity_relation.entity_id").
			Where("entity.initial_episode_code = ?", initEpisodeCodes)

		demandStatusResultQuery = demandStatusResultQuery.
			Joins("join entity on entity.id = note_entity_relation.entity_id").
			Where("entity.initial_episode_code = ?", initEpisodeCodes)

		repairResultQuery.
			Joins("join entity on entity.id = note_entity_relation.entity_id").
			Where("entity.initial_episode_code = ?", initEpisodeCodes)
	}

	// 获取类型个数
	err = resultQuery.
		Where("note.review_feedback_id = ? and note.module_code = 'shot'", reviewFeedbackId).
		Select("note_entity_relation.entity_id as entity_id,note_entity_relation.step_category_id as step_category_id,simpleJSONExtractString(note.json,'reason_type') as reason_type").
		Group("note_entity_relation.entity_id,note_entity_relation.step_category_id,simpleJSONExtractString(note.json,'reason_type')").
		Find(&result).Error

	//必改
	err = markModifyResultQuery.
		Where("note.review_feedback_id = ? and note.module_code = 'shot' and note.mark_modify = 'yes'", reviewFeedbackId).
		Select("note_entity_relation.entity_id as entity_id,note_entity_relation.step_category_id as step_category_id,simpleJSONExtractString(note.json,'reason_type') as reason_type").
		Group("note_entity_relation.entity_id,note_entity_relation.step_category_id,simpleJSONExtractString(note.json,'reason_type')").
		Find(&markModifyResult).Error

	// 接受
	err = demandStatusResultQuery.
		Where("note.review_feedback_id = ? and note.module_code = 'shot' and note.demand_status in ('pending','processing','final')", reviewFeedbackId).
		Select("note_entity_relation.entity_id as entity_id,note_entity_relation.step_category_id as step_category_id,simpleJSONExtractString(note.json,'reason_type') as reason_type").
		Group("note_entity_relation.entity_id,note_entity_relation.step_category_id,simpleJSONExtractString(note.json,'reason_type')").
		Find(&demandStatusResult).Error

	// 返修了的
	err = repairResultQuery.
		Where("note.review_feedback_id = ? and note.module_code = 'shot' and note.demand_status in ('processing','final')", reviewFeedbackId).
		Select("note_entity_relation.entity_id as entity_id,note_entity_relation.step_category_id as step_category_id").
		Group("note_entity_relation.entity_id,note_entity_relation.step_category_id").
		Find(&repairResult).Error

	var stepCategoryCountMap = map[string]uint64{}
	var markModifyCountMap = map[string]uint64{}
	var demandStatusCountMap = map[string]uint64{}
	var repairCountMap = map[string]uint64{}

	// 总计统计
	for _, resultItem := range result {
		mapName := resultItem.StepCategoryId + "_" + resultItem.ReasonType
		if _, ok := stepCategoryCountMap[mapName]; !ok {
			stepCategoryCountMap[mapName] = 1
		} else {
			stepCategoryCountMap[mapName] += 1
		}
	}

	// 必改统计
	for _, markModifyResultItem := range markModifyResult {
		mapName := markModifyResultItem.StepCategoryId + "_" + markModifyResultItem.ReasonType

		if _, ok := markModifyCountMap[mapName]; !ok {
			markModifyCountMap[mapName] = 1
		} else {
			markModifyCountMap[mapName] += 1
		}
	}

	// 接受修改统计
	for _, demandStatusResultItem := range demandStatusResult {
		mapName := demandStatusResultItem.StepCategoryId + "_" + demandStatusResultItem.ReasonType
		if _, ok := demandStatusCountMap[mapName]; !ok {
			demandStatusCountMap[mapName] = 1
		} else {
			demandStatusCountMap[mapName] += 1
		}
	}

	// 返修统计
	for _, repairResultItem := range repairResult {
		if _, ok := repairCountMap[repairResultItem.StepCategoryId]; !ok {
			repairCountMap[repairResultItem.StepCategoryId] = 1
		} else {
			repairCountMap[repairResultItem.StepCategoryId] += 1
		}
	}

	statusService := Status{}
	status, err := statusService.GetStatusCodeMap(map[string]string{
		"filter": fmt.Sprintf("code in (%s)", strings.Join([]string{"'close'", "'wait_for_merge_sequence'"}, ",")),
		"field":  "id,code",
	})
	if err != nil {
		return
	}

	module := model.Module{}
	shotModule, err := module.GetByCode("shot")

	if err != nil {
		return
	}

	// 获取总镜头数
	ShotCountQuery := ClickHouse.DB.Model(&model.Entity{}).
		Where("project_id =? and module_id =? ", projectId, shotModule.Id)

	if initEpisodeCodes != "" {
		ShotCountQuery = ShotCountQuery.Where("initial_episode_code =?", initEpisodeCodes)
	}

	err = ShotCountQuery.Where("simpleJSONExtractUInt(entity.json,'shot_status') not in ?", []int64{status["close"].Id, status["wait_for_merge_sequence"].Id}).
		Select("count(entity_id)").
		Take(&res.ShotCount).Error

	for stepCategoryCountIndex, stepCategoryCountItem := range stepCategoryCountMap {
		stepCategoryCountStr := strings.Split(stepCategoryCountIndex, "_")
		var markModifyCount uint64
		if markModifyCountValue, markModifyCountOk := markModifyCountMap[stepCategoryCountIndex]; markModifyCountOk {
			markModifyCount = markModifyCountValue
		}

		var demandStatusCount uint64
		if demandStatusCountValue, demandStatusCountOk := demandStatusCountMap[stepCategoryCountIndex]; demandStatusCountOk {
			demandStatusCount = demandStatusCountValue
		}

		res.StepCategoryCount = append(res.StepCategoryCount, types.GetShotFeedbackStepCategoryCountItemRes{
			StepCategoryId:    stepCategoryCountStr[0],
			ReasonType:        stepCategoryCountStr[1],
			CategoryCount:     stepCategoryCountItem,
			MarkModifyCount:   markModifyCount,
			DemandStatusCount: demandStatusCount,
		})

		res.RepairRateRes = repairCountMap
	}

	return
}
